﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IWMAG.Scripting.AST.ObjectModel;
using IWMAG.Scripting.Types;
using IWMAG.Scripting.AST.TerminalExpressions;
using IWMAG.Scripting.Interpreter;
using IWMAG.Scripting.AST.Operators;

namespace IWMAG.Scripting.AST.Statements {
    internal class BeginStatement : CodeStatement {
        public CallOperator FunctionCall;

        public BeginStatement(Compiler.Lexeme l, CallOperator val)
            : base(l) {
            FunctionCall = val;
        }

        public override void Verify(Helpers.CompileTable sym, List<Compiler.IUserInfo> error) {
            sym.OpenScope();
            sym.Lookahead[GetType()] = () => {
                return CodeType.Void;
            };
            FunctionCall.Verify(sym, error);
            sym.CloseScope();
        }

        public override IEnumerable<Continuation> Execute(Interpreter.ScriptEngine engine, Helpers.RuntimeTable sym) {
            string methodname = (FunctionCall.Method as VariableExpression).Name;

            RunValue[] args = new RunValue[FunctionCall.Arguments.Count];

            int i = 0;
            foreach (CodeExpression expr in FunctionCall.Arguments) {
                Reference<RunValue> arg = RunValue.NoValue;
                foreach (Continuation wait in expr.ValueOf(engine, sym, arg)) yield return wait;
                args[i++] = arg.ReferencedValue;
            }

            engine.Start(methodname, args);
            yield break;
        }
    }
}
